// Copyright 2011, Vanya Davidenko.
// Кодировка файла: UTF-8. 
package info.iu9.red;
import java.util.Arrays;



class DfaCacheKey {
  static  DfaCacheKey makeEmpty() {
    return new DfaCacheKey();
  }

  static DfaCacheKey make(final int[] dense, final int size, final int c) {
    return new DfaCacheKey(Arrays.copyOf(dense, size), size, c);
  }

  void reset(final int[] dense, final int size, final int c) {
    dense_ = dense;
    size_ = size;
    c_ = c;
    hash_code_ = countHashCode(dense, size, c);
  }

  int sizeInBytes() {
    return ( dense_.length + 1 + 1 + 1 ) * 4;
  }

  public int hashCode() {
    return hash_code_;
  }
  public final boolean equals(final Object o) {
    if ( o == this ) { return true; }

    // но корректно только для final методов.
    if ( !( o instanceof DfaCacheKey ) ) { return false; }

    // Arrays.equals сравнивают массивы целиком, а нам нужна лишь часть.
    final DfaCacheKey s = (DfaCacheKey)o;

    if ( s.size_ != size_ || s.c_ != c_ ) {
      return false;
    }

    for ( int i = 0 ; i != size_ ; i++ ) {
      if ( s.dense_[i] != dense_[i] ) {
        return false;
      }
    }
    return true;
  }


  private DfaCacheKey() {}

  private DfaCacheKey(final int[] dense, final int size, final int c)  {
    reset(dense, size, c);
  }

  private static int countHashCode(final int[] dense, final int size,
                                   final int c) {
    // Скопировано из Arrays.deepHashCode, но берет хэш лишь от начала dense_.
    int hash_code = 1;
    hash_code = 31 * hash_code + c;
    for ( int i = 0 ; i != size ; i++ ) {
      hash_code = 31 * hash_code + dense[i];
    }
    return hash_code;
  }

  private int[] dense_;
  private int size_;
  private int c_;
  private int hash_code_;
}
